<?php

namespace app\model;

use Elasticsearch\ClientBuilder;

/**
 * 搜索模型
 * Class Es
 * @package projects\model
 * @author Du
 * @date 2021/3/16
 * @time 18:09
 */
class Es
{

    private \Elasticsearch\Client $client;
    private string $indexName;
    private string $typeName;

    /**
     * 连接es服务器
     * Es constructor.
     * @param string $indexName 索引名称 类似于数据库名称
     * @param string $typeName 类型名称 类似于表名称
     */
    public function __construct(string $indexName, string $typeName)
    {
        $this->indexName = $indexName;
        $this->typeName = $typeName;
        $host = env('elasticsearch.host') ?: '127.0.0.1';
        $port = env('elasticsearch.port') ?: '9200';
        $this->client = ClientBuilder::create()->setHosts([$host . ':' . $port])->build();
    }

    /**
     * 创建索引
     * @author Du
     * @date 2021/3/16 18:24
     */
    public function createIndex(): bool
    {
        //检测索引是否已存在
        $params_search = [
            'index' => $this->indexName,
        ];
        $flag_exit = $this->client->indices()->exists($params_search);
        if ($flag_exit === false) {
            //创建索引
            $params = [
                'index' => $this->indexName,  //索引名称
                'body' => [
                    'settings' => [
                        'number_of_shards' => 5, // 分片 默认5
                        'number_of_replicas' => 1 // 副本、备份 默认1
                    ]
                ]
            ];
            $response = $this->client->indices()->create($params);
            return true;
        } else {
            return false;
        }
    }

    /**
     * 创建索引类型字段
     * @param array $properties
     * @return bool
     */
    public function createMappings(array $properties = []): bool
    {
        $params = [
            'index' => $this->indexName,  //索引名称 类似数据库名称
            'type' => $this->typeName,   //类型名称 类似表名称
            'body' => [
                //字段定义
                'properties' => $properties,
//                [
//                    //字段全部信息
//                    '字段名称' => [
//                        //属性
//                        'type：类型，可以是text、long、short、date、integer、object等',
//                        'index：是否索引，默认为true',
//                        'store：是否存储，默认为false',
//                        'analyzer：分词器，这里的ik_max_word即使用ik分词器'
//                    ],
//                ]
            ]
        ];
        $response = $this->client->indices()->putMapping($params);
        if ($response && $response['acknowledged'] === true) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 添加数据
     * @param int $id
     * @param array $data
     * @return bool
     */
    public function addData(int $id, array $data): bool
    {
        $params = [
            'index' => $this->indexName,
            'type' => $this->typeName,
            'id' => $id,
            'body' => $data,
        ];
        $response = $this->client->index($params);
        return true;
    }

    /**
     * 更新数据
     * @param int $id
     * @param array $data
     * @return bool
     */
    public function updateData(int $id, array $data): bool
    {
        $params = [
            'index' => $this->indexName,
            'type' => $this->typeName,
            'id' => $id,
            'body' => [
                'doc' => $data
            ]
        ];
        $response = $this->client->update($params);
        return true;
    }

    /**
     * 删除数据
     * @param int $id
     * @return bool
     */
    public function deleteData(int $id): bool
    {
        $params = [
            'index' => $this->indexName,
            'type' => $this->typeName,
            'id' => $id,
        ];
        $response = $this->client->delete($params);
        return true;
    }

    /**
     * 查询数据
     * @param array $filter
     * @param string $orderName
     * @param string $orderSort
     * @param int $start
     * @param int $size
     */
    public function searchData(array $filter, string $orderName, string $orderSort, int $start, int $size)
    {
        $params = [
            'index' => $this->indexName,
            'type' => $this->typeName,
            'body' => $filter,
            'sort' => [$orderName => ['order' => $orderSort]],
        ];
        $results = $this->client->search($params);
        dd($results);
    }

//    /**
//     * 创建指定索引
//     * @author Du
//     * @date 2021/3/27 16:29
//     */
//    public function createIndexWithMapping()
//    {
//        $params = [
//            'index' => 'animal',
//            'body' => [
//                'mappings' => [
//                    'cat' => [
//                        'properties' => [
//                            'name' => [
//                                'type' => 'text'
//                            ],
//                            'age' => [
//                                'type' => 'integer'
//                            ]
//                        ]
//                    ]
//                ],
//                'settings' => [
//                    'number_of_shards' => 5, // 分片 默认5
//                    'number_of_replicas' => 0 // 副本、备份 默认1
//                ]
//            ]
//        ];
//        $response = $this->client->indices()->create($params);
//        dump($response);
//    }
}